package com.hopechart.micro.util;


import com.caucho.hessian.io.HessianSerializerInput;
import com.caucho.hessian.io.HessianSerializerOutput;

import java.io.*;

/**
 * <p>
 *     <br/>序列化工具类
 * </p>
 * @author daijiang@hopechart.com
 * @date 2017-10-30 09:46:20
 * @copyright 杭州鸿泉数字设备有限公司
 * @version V1.0.0
 */
public class SerializationUtil {
    
    private SerializationUtil() {
        super();
    }

    /**
     * @title clone 
     * @description 重写Object克隆方法 
     * @param object 目标对象
     * @return Object
     */
    public static Object clone(Serializable object) {
        return deserialize(serialize(object));
    }
    
    /**
     * @title serialize 
     * @description 序列化 
     * @param obj 目标对象
     * @param outputStream 输出流对象
     * @return void
     */
    public static void serialize(Object obj, OutputStream outputStream) {
        if (null == outputStream) {
            throw new IllegalArgumentException("输出流不能为空！");
        }
        ObjectOutputStream out = null;
        try {
            out = new ObjectOutputStream(outputStream);
            out.writeObject(obj);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
            } catch (IOException ex) {
            }
        }
    }

    /**
     * @title serialize 
     * @description 序列化 
     * @param obj 目标对象
     * @return byte[]
     */
    public static byte[] serialize(Object obj) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
        serialize(obj, baos);
        return baos.toByteArray();
    }

    /**
     * @title deserialize 
     * @description 反序列化 
     * @param inputStream 输入流
     * @return Object
     */
    public static Object deserialize(InputStream inputStream) {
        if (inputStream == null) {
            throw new IllegalArgumentException("输入流不能为空！");
        }
        ObjectInputStream in = null;
        try {
            in = new ObjectInputStream(inputStream);
            return in.readObject();
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(ex);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        } finally {
            try {
                if (null !=in) {
                    in.close();
                }
            } catch (IOException ex) {
            }
        }
    }

    /**
     * @title deserialize 
     * @description 反序列化
     * @param objectData 目标对象
     * @return Object
     */
    public static Object deserialize(byte[] objectData) {
        if (null == objectData) {
            throw new IllegalArgumentException("byte[]数据不能为空！");
        }
        ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
        return deserialize(bais);
    }

    /**
     * Hessian实现序列化
     * @param object 目标对象
     * @return byte[]
     */
    public static byte[] hessianSerialize(Object object) {
		if (object == null) {
			throw new IllegalArgumentException("目标对象不能为空！");
		}
		ByteArrayOutputStream os = null;
		try {
			os = new ByteArrayOutputStream();
			new HessianSerializerOutput(os).writeObject(object);
			os.flush();
			return os != null ? os.toByteArray() : null;
		} catch (IOException e) {
			throw new RuntimeException("Hessian序列化异常！", e);
		} finally {
			if(null != os) {
				try {
	                os.close();
                } catch (IOException e) {
                }
			}
		}
	}

    /**
     * Hessian反序列化
     * @param bytes 目标数据
     * @return
     * @throws Exception
     */
	public static Object hessianDeserialize(byte[] bytes){
		if (null == bytes) {
			throw new IllegalArgumentException("byte[]数据不能为空！");
		}
		ByteArrayInputStream is = new ByteArrayInputStream(bytes);
		try {
	        return new HessianSerializerInput(is).readObject();
        } catch (IOException e) {
        	throw new RuntimeException("Hessian反序列化异常！", e);
        } finally {
        	if(null != is) {
        		try {
	                is.close();
                } catch (IOException e) {
                }
        	}
        }
	}
    
}
